package model.algorithms.rounding;

import java.util.LinkedHashMap;

import model.components.networks.network.VirtualNetwork;
import model.components.networks.network.PhysicalNetwork;
import model.components.nodes.node.VirtualNode;
import model.components.nodes.node.PhysicalNode;

public class Deterministic2 extends RoundingAlgorithm
{
	public Deterministic2( String name )
	{
		super( name );
	}
	
	@Override
	public LinkedHashMap< VirtualNode, PhysicalNode > run( VirtualNetwork virtualNetwork, PhysicalNetwork physicalNetwork, double x[][][], double f[][][] )
	{
		LinkedHashMap< VirtualNode, PhysicalNode > mappingNodes = new LinkedHashMap< VirtualNode, PhysicalNode >();
		
		double nodesSubSel[] = new double[ physicalNetwork.getNodes().size() ];
		double sumFlows[] = new double[ physicalNetwork.getNodes().size() ];
		boolean control = true;
		
		for( VirtualNode nodeRequest: virtualNetwork.getVirtualNodes() )
		{
			int iNodeReq = nodeRequest.getNumber();
			double sumFlowsMax = -1;
			int iNodeSubMax = 0;
			PhysicalNode nodeSubSel = null;
			
			for( PhysicalNode nodeSubstrate: physicalNetwork.getPhysicalNodes() )
				if( nodeRequest.getType().equalsIgnoreCase( nodeSubstrate.getType() ) )
				{
					int iNodeSub = nodeSubstrate.getNumber();
					int iNodeAug = nodeSubstrate.getNumber() + virtualNetwork.getNodes().size();
					
					for( int i = 0; i < virtualNetwork.getVirtualLinks().size(); i++ )
						sumFlows[ iNodeSub ] += x[ i ][ iNodeReq ][ iNodeAug ] * ( f[ i ][ iNodeReq ][ iNodeAug ] + f[ i ][ iNodeAug ][ iNodeReq ] );
					
					if( sumFlows[ iNodeSub ] > sumFlowsMax && nodesSubSel[ iNodeSub ] == 0 )
					{
						sumFlowsMax = sumFlows[ iNodeSub ];
						iNodeSubMax = iNodeSub;
						nodeSubSel = nodeSubstrate;
					}
				}
			
			if( sumFlowsMax != 0 )
			{
				nodesSubSel[ iNodeSubMax ] = 1;
				mappingNodes.put( nodeRequest, nodeSubSel );
			}
			else	control = false;
		}
		
		if( control == false )	mappingNodes = null;
		
		return mappingNodes;
	}
	
}
